<?php

namespace app\db\model;

use think\Db;
use think\Model;

class DbTemplateRelationQuestionOption extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $dbName     = 'db_template_relation_question_option';

    # --------------------------------- 查询类接口 START------------------------------------
    /**
     * 根据变量id获取变量选项
     * @param [type] $question_id 变量id
     * @param [type] $template_id 模板id
     * @param [type] $is_hide     是否需要隐藏的选项 true需要 false不需要
     * @author MSQ   2021-8-5
     */
    public function getQuestionOptionByQid($question_id = 0,$template_id = 0,$field = '',$is_hide = true)
    {
        if (!$question_id || !$template_id) return false;
        $where = [
            'r.question_id' => $question_id,
            'r.template_id' => $template_id,
            'r.status'      => 1,
            'o.status'      => 1,
        ];
        # 不需要隐藏的选项 
        # 目前系统是不支持显示/隐藏选项的，但同步了原系统一部分处于隐藏状态的数据
        # 为兼容原系统数据 同步模板等操作时is_hide为true 查询、验证等is_hide为false
        if (!$is_hide) $where['r.show_status'] = 1;

        if (!$field) $field = 'r.option_id,o.option_key,r.question_id,r.option_name,o.is_other,r.show_status';

        $list = db($this->dbName)->alias('r')
            ->field($field)
            ->join('db_question_option o','o.id=r.option_id')
            ->where($where)->select();
        if (!$list) return [];
        return $list;
    }
    /**
     * 根据模板id和question_id获取所有选项
     * @param  [type] $template_id 模板id
     * @param  [type] $question_id 问题id或问题id数组
     * @param [type] $is_hide     是否需要隐藏的选项 true需要 false不需要
     * @return [type]              [description]
     */
    public function getOptionListByQuestionId($template_id,$question_id,$field = '',$is_hide = true)
    {
        if (!$template_id || !$question_id) return [];

        # 根据模板id和question_id获取题目
        $where = [
            'r.template_id'   => $template_id,
            'r.status'        => 1,//未删除
            'o.status'        => 1,//正常
        ];
        if (!$is_hide) $where['r.show_status'] = 1;

        if (is_array($question_id)) {
            $where['o.question_id'] = ['IN',$question_id];
        } else {
            $where['o.question_id'] = $question_id;
        }
        if (!$field) $field = 'r.option_id,o.option_key,o.question_id,o.is_other,o.create_type,r.option_name,r.weight,r.show_status,o.create_time';
        # 获取所有选项数据
        return db($this->dbName)->alias('r')
            ->join('db_question_option o',' o.id = r.option_id')
            ->field($field)
            ->where($where)
            ->order('r.weight DESC,o.weight DESC,o.id ASC')
            ->select();
    }
    /**
     * 根据模板id和question_id获取所有选项
     * @param  [type] $template_id 模板id
     * @param  [type] $question_id 问题id或问题id数组
     * @param [type] $is_hide     是否需要隐藏的选项 true需要 false不需要
     * @return [type]              [description]
     * @author MSQ   2021-8-5
     */
    public function getOptionListByQId($template_id,$question_id,$field = '',$is_hide = true)
    {
        if (!$template_id || !$question_id) return [];

        # 根据模板id和question_id获取题目
        $where = [
            'r.template_id'   => $template_id,
            'r.status'        => 1,//未删除
            'o.status'        => 1,//正常
        ];
        # 不需要隐藏的选项 
        # 目前系统是不支持显示/隐藏选项的，但同步了原系统一部分处于隐藏状态的数据
        # 为兼容原系统数据 同步模板等操作时is_hide为true 查询、验证等is_hide为false
        if (!$is_hide) $where['r.show_status'] = 1;

        if (is_array($question_id)) {
            $where['o.question_id'] = ['IN',$question_id];
        } else {
            $where['o.question_id'] = $question_id;
        }
        if (!$field) $field = 'r.option_id,o.option_key,o.question_id,o.is_other,o.create_type,r.option_name,r.weight,r.show_status,o.create_time';
        # 获取所有选项数据
        return db($this->dbName)->alias('r')
            ->join('db_question_option o',' o.id = r.option_id')
            ->field($field)
            ->where($where)
            ->order('r.weight DESC,o.weight DESC,o.id ASC')
            ->select();
    }
    /**
     * 获取模板所有选项
     * @param  [type] $template_id 模板id
     * @author MSQ   2021-8-25
     */
    public function getOptionListByTemplateId($template_id)
    {
        if (!$template_id) return [];

        $where = [
            'template_id' => $template_id,
            'status'      => 1,
        ];
        $list = db($this->dbName)->where($where)->select();
        return $list;
    }
    # ---------------------------------- 查询类接口 END-------------------------------------


    # ------------------------------- 数据处理类接口 START ----------------------------------
    /**
     * 根据模板ID生成option关联
     * @param [type] $origin_template_id 来源模板id
     * @param [type] $template_id        需要生成关联的模板id
     * @param [type] $database_id        需要生成关联的数据库id
     * @author MSQ   2021-8-3
     */
    public function addTemplateRelationOptionByTemplateId($origin_template_id = 0,$template_id = 0,$database_id = 0,$where_ori = [])
    {
        if (!$origin_template_id || !$template_id || !$database_id) return false;

        if (!$where_ori) {
            # 无自定义where
            $where_ori = [
                'template_id' => $origin_template_id
            ];
        }
        # 固定查询status
        $where_ori['status'] = 1;

        # 原模板关联的option
        $relationList = db($this->dbName)->where($where_ori)->select();
        if (!$relationList) return true;

        $newRelationList = array_chunk($relationList,1000);        
        foreach ($newRelationList as $k_a => $v_a) {
            $addTemplateRelationData = [];
            foreach ($v_a as $k_b => $v_b) {
                $addTemplateRelationData[] = [
                    'template_id'   => $template_id,
                    'database_id'   => $database_id,
                    'question_id'   => $v_b['question_id'],
                    'option_id'     => $v_b['option_id'],
                    'option_name'   => $v_b['option_name'],
                    'weight'        => $v_b['weight'],
                    'show_status'   => $v_b['show_status'],
                ];
            }
            // $res = $this->saveAll($addTemplateRelationData);
            $res = $this->setAttr('id',null)->isUpdate(false)->saveAll($addTemplateRelationData);
            if (!$res) return false;
        }
        return true;
    }
    /**
     * 创建关联选项
     * @param [type] $question_id 变量id
     * @param [type] $template_id 需要生成关联的模板id
     * @param [type] $database_id 需要生成关联的数据库id
     * @author MSQ   2021-8-12
     */
    public function createRelationOption($question_id = 0,$template_id = 0,$database_id = 0)
    {
        if (!$question_id || !$template_id) return false;

        if (!$database_id) $database_id = model('DbTemplate')->getDetails($template_id,'database_id');
        if (!$database_id) return false;

        # 获取问题的选项列表
        $optionList = model('DbQuestionOption')->getQuestionOptionByQid($question_id);
        if (!$optionList) return true;
        $where = [
            'question_id' => $question_id,
            'template_id' => $template_id,
            'option_id'   => ['IN',array_column($optionList,'id')],
            'status'      => 1,
        ];
        # 已经存在选项
        $existOption = db($this->dbName)->where($where)->select();
        # 添加选项关联的数据
        $addData = [];
        foreach ($optionList as $k_o => $v_o) {
            # 检测选项是否已存在
            if (isset($existOption[$v_o['id']])) continue;

            $addData[] = [
                'template_id' => $template_id,
                'database_id' => $database_id,
                'question_id' => $v_o['question_id'],
                'option_id'   => $v_o['id'],
                'option_name' => $v_o['option_name'],
                'weight'      => $v_o['weight'],
            ];
        }
        if ($addData) {
            // $addRes = $this->saveAll($addData);
            $addRes = $this->setAttr('id',null)->isUpdate(false)->saveAll($addData);
            if (!$addRes) return false;
        }
        return true;
    }
    /**
     * 根据模板id及选项id删除选项
     * @param [type] $question_id 变量id
     * @param [type] $template_id 需要生成关联的模板id
     * @param [type] $database_id 需要生成关联的数据库id
     * @author MSQ   2021-8-12
     */
    public function deleteByTemplateAndOptionIds($template_id = 0,$option_ids = [])
    {
        if (!$template_id || !$option_ids) return false;

        $relevantTemplateId = model('DbTemplate')->getChildDbOrTemplate($template_id,2);
        if (!$relevantTemplateId) return false;

        if (!is_array($option_ids)) $option_ids = [$option_ids];

        $where = [
            'option_id'   => ['IN',$option_ids],
            'template_id' => ['IN',$relevantTemplateId],
            'status'      => 1,
        ];
        return $this->update(['status' => 0],$where);
        # 编辑变量时删除多余选项 会先删总表再删关联表 故而此处没有检索跨总库删除总表数据
    }
    /**
     * 根据选项id创建关联选项
     * @param [type] $option_ids  选项id
     * @param [type] $template_id 需要生成关联的模板id
     * @param [type] $database_id 需要生成关联的数据库id
     * @author MSQ   2021-8-12
     */
    public function createRelationOptionByOptionIds($option_ids = 0,$template_id = 0,$database_id)
    {
        if (!$option_ids || !$template_id) return false;

        if (!$database_id) $database_id = model('DbTemplate')->getDetails($template_id,'database_id');
        if (!$database_id) return false;

        if (!is_array($option_ids)) $option_ids = [$option_ids];

        # 获取问题的选项列表
        $where = [
            'id'     => ['IN',$option_ids],
            'status' => 1,
        ];
        $optionList = model('DbQuestionOption')->where($where)->select();
        if (!$optionList) return true;
        $where = [
            // 'question_id' => $question_id,
            'template_id' => $template_id,
            'option_id'   => ['IN',array_column($optionList,'id')],
            'status'      => 1,
        ];
        # 已经存在选项
        $existOption = db($this->dbName)->where($where)->select();
        # 添加选项关联的数据
        $addData = [];
        foreach ($optionList as $k_o => $v_o) {
            # 检测选项是否已存在
            if (isset($existOption[$v_o['id']])) continue;

            $addData[] = [
                'template_id' => $template_id,
                'database_id' => $database_id,
                'question_id' => $v_o['question_id'],
                'option_id'   => $v_o['id'],
                'option_name' => $v_o['option_name'],
                'weight'      => $v_o['weight'],
            ];
        }
        if ($addData) {
            // $addRes = $this->saveAll($addData);
            $addRes = $this->setAttr('id',null)->isUpdate(false)->saveAll($addData);
            if (!$addRes) return false;
        }
        return true;
    }
    /**
     * 删除整个模板下选项
     * @param [type] $template_id 模板id
     * @author MSQ   2021-8-21
     */
    public function deleteDataByTemplate($template_id = [])
    {
        if (!$template_id) return false;
        if (!is_array($template_id)) $template_id = [$template_id];

        $where = [
            'status'      => 1,
            'template_id' => ['IN',$template_id]
        ];
        # 所有要删除的option
        $relevantOption = db($this->dbName)->where($where)->group('option_id')->column('option_id');
        if (!$relevantOption) return false;

        # 是否有跨总库模板引用该目录/模块
        $where['option_id'] = ['IN',$relevantOption];
        $where['template_id'] = ['NOT IN',$template_id];
        # 查找跨总库的option
        $otherSyncOption = db($this->dbName)->where($where)->group('option_id')->column('option_id');

        $where = [
            'status'      => 1,
            'template_id' => ['IN',$template_id]
        ];
        # 删除相关模板的关联option
        $res = $this->update(['status' => 0],$where);
        if (!$res) return false;
        
        # 差集 即没有跨总库引用 可删除总表option
        $deleteOptions = array_diff($relevantOption,$otherSyncOption);
        if (!$deleteOptions) return true;

        $res = model('DbQuestionOption')->deleteOptions($deleteOptions);
        if (!$res) return false;

        return true;
    }
    # --------------------------------- 数据处理类接口 END ----------------------------------
}
